package com.kingyea.mobilepolice.apimanage.systemsync;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.kingyea.mobilepolice.apimanage.systemsync.bean.InvokedMethod;
import com.kingyea.mobilepolice.apimanage.utils.GlobalVar;
import com.kingyea.mobilepolice.apimanage.utils.StateCode;
import com.kingyea.mobilepolice.system.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Mr.Lin
 * @version v1.0.0
 * @description
 * @date Created in 2018/3/1 19:14
 */
@Service
public class SystemSyncService {

    private static final Logger LOGGER = LoggerFactory.getLogger(SystemSyncService.class);

    @Resource(name = "restTemplateNei")
    private RestTemplate restTemplate;

//    private static SystemSyncService systemSyncService;

//    @PostConstruct
//    public void init() {
//        systemSyncService = this;
//        systemSyncService.restTemplate = this.restTemplate;
//    }

    /**
     * @Description: 外网定时通知内网同步数据 并且 把数据发送给内网
     * * 外网工程执行的同步任务：
     * 1.发送本地token同步信息到内网
     * 2.从内网获取token同步信息到本地
     * @Param: []
     * @return: void
     * @Author: cxc
     * @Date: 2018.04.20 11:28
     */
//    @Scheduled(cron = "0/5 * * * * ?")
    public void syncJob() {
        if (GlobalVar.inside.intValue() == GlobalVar.insideWai) {
            // 1、MQ拉取需要内网同步的数据
//            Result<List<Object>> resultObj = Result.getSuccessResult(ActiveMqUtils.getInvokeMethodList());
//            List<Object> list = ActiveMqUtils.getInvokeMethodList();
            // todo 这里可以获取外网需要同步的内容推送到内网
            List<Object> list = Lists.newArrayList();// todo 暂时没考虑外网普通数据推向内部，如果需要推普通数据，一样需要解决Send2Queue注解带来的无限循环
            sync(list);
        }
    }

    public void sync(List<Object> list) {
        Result<List<InvokedMethod>> result = Result.getSuccessResult(list.stream().map(bean -> JSON.parseObject(((String) bean), InvokedMethod.class)).collect(Collectors.toList()));
        // 2、把数据发送到内网接收数据的接口
        System.out.println("发送将要同步的方法：" + JSON.toJSONString(result));
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        // 发送到内网网关，并且获取 内网需要同步的数据 放到队列
        result = restTemplate.postForObject(GlobalVar.insideAddress + "/api/syssync/queue", new HttpEntity<Result<List<InvokedMethod>>>(result, headers), new Result<List<InvokedMethod>>().getClass());
        // 3、返回数据是外网需要同步的数据，加入到内存队列
        toQueue(result);
    }

    private void toQueue(Result<List<InvokedMethod>> result) {
        System.out.println("获取将要同步的方法：" + JSON.toJSONString(result));
        if (StateCode.OPERATION_SUCCESS.equals(result.getCode()) && result != null && result.getData() != null && result.getData().size() != 0) {
            List<InvokedMethod> invokedMethodList = JSON.parseArray(JSON.toJSONString(result.getData()), InvokedMethod.class);
            for (InvokedMethod method : invokedMethodList) {
                SyncThread.toBeInvokSyncQueue.offer(method);// 入列
            }
        }
    }

}
//@Component
//public class SystemSyncService {
//
//    private static final Logger LOGGER = LoggerFactory.getLogger(SystemSyncService.class);
//
//    public static LinkedBlockingQueue<InvokedMethod> toBeInvokSyncQueue = new LinkedBlockingQueue();// 待执行队列
//
//    @Value("${kingyea.mobilepolice.inside}")
//    private Integer inside;// TODO: 2018/4/26 目前好像同步功能只有外网获取内网数据(前期主要是只思考同步设置部分的信息)，并没有把外网数据推送到内网
//
//    @PostConstruct
//    public void initTask() {
//        if (inside.intValue() == GlobalVar.insideWai) {
//            ScheduledExecutorService syncToeknServer4wai = Executors.newSingleThreadScheduledExecutor();
//            ScheduledFuture <?> scheduledFuture = syncToeknServer4wai.scheduleWithFixedDelay(() -> {
//                try {
//                    syncJob();
//                } catch (Throwable e) {
//                    e.printStackTrace();
//                }
//            }, 0, 5, TimeUnit.SECONDS);
//        }
//    }
//
//    /**
//     * 外网工程执行的同步任务
//     **/
////    @Scheduled(cron = "0/5 * * * * ?")
//    public void syncJob() {
//        if (GlobalVar.inside.intValue() == GlobalVar.insideWai ) {
////        if(true&&toBeInvokSyncQueue.size()<1000){
//            refreshToBeinvokServiceMessage();
//            invokService();
//        }
//    }
//
//    @Autowired
//    private HttpUtil httpUtil;
//
//    /**
//     * 刷新需要同步的service操作队列
//     *
//     * @param
//     * @return void
//     * @author Mr.Lin
//     * @date 2018/3/2 9:51
//     */
//    public void refreshToBeinvokServiceMessage() {
//        String insideAddress = GlobalVar.insideAddress;
//        String resultStr = HttpUtil.invokeUrl(insideAddress + "/api/syssync/queue", new HashMap(), new HashMap<>(), HttpMethod.POST);
////        String resultStr = null;
////        try {
////            resultStr = httpUtil.invokeUrl2(insideAddress + "/api/syssync/queue", new HashMap(), new HashMap<>(), HttpMethod.GET);
////        } catch (Exception e) {
////            e.printStackTrace();
////        }
//        if (!StringUtils.isEmpty(resultStr)) {
//            System.out.println("获取将要同步的方法：" + resultStr);
//            Result<List<String>> result;
//            try {
//                result = JSON.parseObject(resultStr, Result.class);
//            } catch (Exception e) {
//                LOGGER.error("获取将要同步的方法成功，但是格式有误：" + resultStr);
//                throw e;
//            }
//            if (result.getCode().equalsIgnoreCase ( StateCode.OPERATION_SUCCESS ) && result != null && result.getData() != null && result.getData().size() != 0) {
//                List<String> methods = result.getData();
//                for (String method : methods) {
//                    toBeInvokSyncQueue.offer(JSON.parseObject(method, InvokedMethod.class));
//                }
//            }
//        }
//    }
//
//    /**
//     * 执行service调用
//     *
//     * @param
//     * @return void
//     * @author Mr.Lin
//     * @date 2018/3/2 9:55
//     */
//    public void invokService() {
//        InvokedMethod targetService = toBeInvokSyncQueue.peek();// 获取不移除
//        SyncInvokMethodProxy syncInvokMethodProxy = new SyncInvokMethodProxy();
//        while (targetService != null) {
//            syncInvokMethodProxy.invokService(targetService);
//            toBeInvokSyncQueue.poll();// 获取并移除
//            targetService = toBeInvokSyncQueue.peek();
//        }
//    }
//
//
//
//
//}
